import data from "../../../../core/cache_data";
import { ReplacePageAni } from "../../../../core/game";
import Utils, { Sync } from "../../../../core/utils";
import ReactNode from "../../../../prefabs/react_node";
import CCCharacter from "../../../eggy/cc_game/cc_character";
import { Character } from "../../../eggy/game/character";
import { GameUtils } from "../../../eggy/game_utils";
import { Network } from "../../../net/network";
import { ProtocolObjectRoom, ProtocolC2SRegUser, ProtocolS2CRegUser, ProtocolC2SLoginUser, ProtocolS2CLoginUser, ProtocolC2SGetRoom, ProtocolS2CGetRoom, ProtocolC2SNewRoom, ProtocolS2CNewRoom, ProtocolC2SEnterRoom, ProtocolS2CEnterRoom } from "../../../net/protocol_dist";
import { User } from "../../../net/user";
import EditEggyLobbyPanel from "./edit_eggy_lobby_panel";

const { ccclass, property } = cc._decorator;

@ccclass
export default class PageLobbyReady extends cc.Component {
    @property(cc.EditBox)
    ebUrl: cc.EditBox = null;
    @property(cc.Node)
    ccCharContain: cc.Node = null;
    @property(cc.Prefab)
    newEggyPanelPrefab: cc.Prefab = null;

    @property(ReactNode)
    cursorRn: ReactNode = null;

    _blocked = false;

    users: Character[] = [];
    protected onLoad(): void {
        this.ebUrl.string = data.storage.get("page-lobby-ready", "");
        let users = data.storage.get("page-lobby-users", []);
        users.forEach(char => {
            this.addCCChar(char);
        });
    }

    onClickNew() {
        let panel = cc.instantiate(this.newEggyPanelPrefab).getComponent(EditEggyLobbyPanel);
        Utils.game.resPushNode({
            baseOn: "page",
            prefab: panel.node
        });
        panel.once("char", (char: Character) => {
            this.addCCChar(char);
            this.users.push(char);
            data.storage.set("page-lobby-users", this.users);
        }, this);
    }
    addCCChar(char: Character) {
        let ccChar = GameUtils.InstantiateCCGameCom("eggy", CCCharacter);
        this.ccCharContain.addChild(ccChar.node);
        ccChar.setData(char);
        ccChar.touch.on(cc.Node.EventType.TOUCH_END, () => {
            this.cursorRn.setTarget(ccChar.node);
        });
    }
    async onClickStart() {
        if (this._blocked) {
            return;
        }
        if (!this.cursorRn.target) {
            return;
        }
        this._blocked = true;
        data.storage.set("page-lobby-ready", this.ebUrl.string);

        Utils.blocker.show();
        await Network.Init(this.ebUrl.string);
        Utils.blocker.hide();

        if (Network.state !== "connected") {
            Utils.blocker.hide();
            await Utils.game.msgBoxSync("网络连接失败。请重试");
            this._blocked = true;
            Utils.game.resReplacePage({
                name: "page_lobby_ready",
                ani: ReplacePageAni.Fade
            });
            return;
        }
        let ccChar = this.cursorRn.target.getComponent(CCCharacter);
        User.userId = ccChar.character.uuid;

        let room: ProtocolObjectRoom = null;

        Utils.blocker.show();
        //注册账号 / 登录账号
        while (1) {
            if (!User.userId) {
                let msg = new ProtocolC2SRegUser();
                let rtn = await Network.SendAndWaitRecv(msg, ProtocolS2CRegUser);
                if (!rtn.ok) {
                    //todo:
                    await Sync.DelayTime(1.0);
                    continue;
                }
                User.userId = rtn.user.token;
            }
            else {
                let msg = new ProtocolC2SLoginUser();
                msg.token = User.userId;
                let rtn = await Network.SendAndWaitRecv(msg, ProtocolS2CLoginUser);
                if (!rtn.ok) {
                    //todo:
                    User.userId = "";
                    await Sync.DelayTime(1.0);
                    continue;
                }
            }
            break;
        }
        //账号绑定char
        {
            ccChar.owner = User.userId;
            data.save();
        }
        {
            //加入房间
            let msg = new ProtocolC2SGetRoom();
            msg.id = 1;
            let rtn = await Network.SendAndWaitRecv(msg, ProtocolS2CGetRoom);
            if (!rtn.ok) {
                //todo:
                let msg = new ProtocolC2SNewRoom();
                let rtn2 = await Network.SendAndWaitRecv(msg, ProtocolS2CNewRoom);
                room = rtn2.room;
            }
            else {
                room = rtn.room;
            }
        }

        {
            let msg = new ProtocolC2SEnterRoom();
            msg.id = room.id;
            let rtn = await Network.SendAndWaitRecv(msg, ProtocolS2CEnterRoom);
            if (!rtn.ok) {
                //todo:
            }
            room = rtn.room;
        }
        Utils.blocker.hide();

        data.cache.set("char", ccChar.toArrData());
        User.room = room;

        data.save();

        Utils.game.resReplacePage({
            name: "page_lobby_game",
            ani: ReplacePageAni.Fade
        });
    }
};